home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
netprog.zip
/
NETPROG.TAR
/
lib
/
daemon.c
next >
Wrap
C/C++ Source or Header
|
1989-12-17
|
3KB
|
135 lines
/*
* Initialize a daemon process.
*/
#include <stdio.h>
#include <signal.h>
#include <sys/param.h>
#include <errno.h>
extern int errno;
#ifdef SIGTSTP /* true if BSD system */
#include <sys/file.h>
#include <sys/ioctl.h>
#endif
/*
* Detach a daemon process from login session context.
*/
daemon_start(ignsigcld)
int ignsigcld; /* nonzero -> handle SIGCLDs so zombies don't clog */
{
register int childpid, fd;
/*
* If we were started by init (process 1) from the /etc/inittab file
* there's no need to detach.
* This test is unreliable due to an unavoidable ambiguity
* if the process is started by some other process and orphaned
* (i.e., if the parent process terminates before we are started).
*/
if (getppid() == 1)
goto out;
/*
* Ignore the terminal stop signals (BSD).
*/
#ifdef SIGTTOU
signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
/*
* If we were not started in the background, fork and
* let the parent exit. This also guarantees the first child
* is not a process group leader.
*/
if ( (childpid = fork()) < 0)
err_sys("can't fork first child");
else if (childpid > 0)
exit(0); /* parent */
/*
* First child process.
*
* Disassociate from controlling terminal and process group.
* Ensure the process can't reacquire a new controlling terminal.
*/
#ifdef SIGTSTP /* BSD */
if (setpgrp(0, getpid()) == -1)
err_sys("can't change process group");
if ( (fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling tty */
close(fd);
}
#else /* System V */
if (setpgrp() == -1)
err_sys("can't change process group");
signal(SIGHUP, SIG_IGN); /* immune from pgrp leader death */
if ( (childpid = fork()) < 0)
err_sys("can't fork second child");
else if (childpid > 0)
exit(0); /* first child */
/* second child */
#endif
out:
/*
* Close any open files descriptors.
*/
for (fd = 0; fd < NOFILE; fd++)
close(fd);
errno = 0; /* probably got set to EBADF from a close */
/*
* Move the current directory to root, to make sure we
* aren't on a mounted filesystem.
*/
chdir("/");
/*
* Clear any inherited file mode creation mask.
*/
umask(0);
/*
* See if the caller isn't interested in the exit status of its
* children, and doesn't want to have them become zombies and
* clog up the system.
* With System V all we need do is ignore the signal.
* With BSD, however, we have to catch each signal
* and execute the wait3() system call.
*/
if (ignsigcld) {
#ifdef SIGTSTP
int sig_child();
signal(SIGCLD, sig_child); /* BSD */
#else
signal(SIGCLD, SIG_IGN); /* System V */
#endif
}
}